/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.yzbdl.lanius.orchestrate.serv.service.task.impl;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yzbdl.lanius.orchestrate.common.constant.Const;
import org.yzbdl.lanius.orchestrate.common.dto.task.TaskPlanQueryDTO;
import org.yzbdl.lanius.orchestrate.common.dto.task.TaskPlanResourceDTO;
import org.yzbdl.lanius.orchestrate.common.entity.resource.ServerProgramEntity;
import org.yzbdl.lanius.orchestrate.common.entity.resource.TaskResourceConfigEntity;
import org.yzbdl.lanius.orchestrate.common.entity.task.TaskPlan;
import org.yzbdl.lanius.orchestrate.common.entity.task.TaskPlanGroup;
import org.yzbdl.lanius.orchestrate.common.enums.ResourceDataStatusEnum;
import org.yzbdl.lanius.orchestrate.common.enums.TaskStatusEnum;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.BusinessException;
import org.yzbdl.lanius.orchestrate.common.result.ResultTypeEnum;
import org.yzbdl.lanius.orchestrate.common.utils.MessageUtil;
import org.yzbdl.lanius.orchestrate.common.utils.SpecialCharacterUtil;
import org.yzbdl.lanius.orchestrate.common.utils.cron.CronUtils;
import org.yzbdl.lanius.orchestrate.common.vo.task.ScheduleTaskPlanVO;
import org.yzbdl.lanius.orchestrate.common.vo.task.TaskPlanVO;
import org.yzbdl.lanius.orchestrate.common.vo.task.schedule.AddTaskPlanJobVO;
import org.yzbdl.lanius.orchestrate.common.vo.task.schedule.UpdateTaskPlanJobStatusVO;
import org.yzbdl.lanius.orchestrate.serv.constant.TaskJsonConfigConstant;
import org.yzbdl.lanius.orchestrate.serv.constant.TaskPlanSchedulerConstant;
import org.yzbdl.lanius.orchestrate.serv.mapper.task.TaskPlanMapper;
import org.yzbdl.lanius.orchestrate.serv.quartz.config.QuartzJobManager;
import org.yzbdl.lanius.orchestrate.serv.quartz.taskplan.TaskPlanQuartzTaskJob;
import org.yzbdl.lanius.orchestrate.serv.service.resource.ServerProgramService;
import org.yzbdl.lanius.orchestrate.serv.service.task.TaskInstanceService;
import org.yzbdl.lanius.orchestrate.serv.service.task.TaskPlanGroupService;
import org.yzbdl.lanius.orchestrate.serv.service.task.TaskPlanService;
import org.yzbdl.lanius.orchestrate.serv.utils.CommonUtil;
import org.yzbdl.lanius.orchestrate.serv.utils.TaskScheduleJobUtil;
import org.yzbdl.lanius.orchestrate.serv.utils.cron.CronParserUtil;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 任务编排service实现类
 *
 * @author jinchunzhao@yzbdl.ac.cn
 * @date 2022-04-07 10:06
 */
@Service
@Slf4j
public class TaskPlanServiceImpl extends ServiceImpl<TaskPlanMapper, TaskPlan> implements TaskPlanService {

    @Autowired
    private TaskInstanceService taskInstanceService;

    @Autowired
    private QuartzJobManager quartzJobManager;

    @Autowired
    private ServerProgramService serverProgramService;

    @Autowired
    private TaskPlanGroupService taskPlanGroupService;

    @Override
    public IPage<TaskPlanVO> queryPage(Page<TaskPlanVO> page, TaskPlanQueryDTO taskPlanQueryDto) {
        taskPlanQueryDto.setKeyword(SpecialCharacterUtil.escapeStr(taskPlanQueryDto.getKeyword()));
        IPage<TaskPlanVO> iPage = this.baseMapper.queryPage(page, taskPlanQueryDto);
        List<TaskPlanVO> records = iPage.getRecords();
        for (TaskPlanVO taskPlanVO : records) {
            String taskCron = taskPlanVO.getTaskCron();
            String translateToCn = CronParserUtil.translateToCn(taskCron);
            taskPlanVO.setTaskCronDes(translateToCn);
        }
        iPage.setRecords(records);

        return iPage;
    }

    @Override
    public Boolean saveEntity(TaskPlan taskPlan) {
        // 校验任务配置json格式
        validTaskJsonConfig(taskPlan.getJsonConfig());
        taskPlan.setId(null);
        // 校验是否存在同名的任务编排名称
        checkTaskPlaExist(taskPlan);
        boolean save = this.save(taskPlan);
        if (save) {
            // 添加JOB
            this.addTaskJob(this.buildAddTaskPlanJobVO(taskPlan));
            return Boolean.TRUE;
        }
        throw new BusinessException(MessageUtil.get("task.add_error"));
    }

    @Override
    public Boolean updateEntity(TaskPlan taskPlan) {
        if (Objects.isNull(taskPlan.getId())) {
            throw new BusinessException(MessageUtil.get("task.update.id_not_empty"));
        }
        TaskPlan tempTaskPlan = this.getById(taskPlan.getId());
        Integer sysStatus = tempTaskPlan.getStatus();
        if (Objects.equals(sysStatus, TaskStatusEnum.ENABLED.getCode())) {
            throw new BusinessException(MessageUtil.get("task.update.status_enable_msg"));
        }
        // 校验任务配置json格式
        validTaskJsonConfig(taskPlan.getJsonConfig());
        // 校验是否存在同名的任务编排名称
        checkTaskPlaExist(taskPlan);
        boolean update = this.updateById(taskPlan);
        if (update) {
            Integer status = taskPlan.getStatus();
            // 校验待禁用的任务编排是否存在正在运行中的任务实例
            if (Objects.equals(status, TaskStatusEnum.DISABLED.getCode())) {
                // 查询任务实例的状态（初始化中、运行中、暂停（手动）、等待中）不可以删除、禁用
                Boolean run = taskInstanceService.checkInstanceForRun(taskPlan.getId());
                if (run) {
                    throw new BusinessException(MessageUtil.get("task.status_executing_task_not_disable"));
                }
            }
            TaskPlan plan = this.getById(taskPlan.getId());
            taskPlan.setOrgId(plan.getOrgId());
            // 更新JOB频率、参数
            this.updateTaskJobCronAndParam(this.buildAddTaskPlanJobVO(taskPlan), status);
            return Boolean.TRUE;
        }
        throw new BusinessException(MessageUtil.get("task.update_error"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteEntity(Long id) throws Exception {

        // 校验待删除的任务编排是否在启用状态
        TaskPlan taskPlan = this.getById(id);
        if (Objects.isNull(taskPlan)) {
            throw new BusinessException(MessageUtil.get("task.not_exist"));
        }
        if (Objects.equals(taskPlan.getStatus(), TaskStatusEnum.ENABLED.getCode())) {
            throw new BusinessException(MessageUtil.get("task.delete.status_check_msg"));
        }
        boolean remove = this.removeById(id);
        if (remove) {
            taskInstanceService.deletedByTaskPlanId(taskPlan.getOrgId(), taskPlan.getGroupId(), id);
            // 删除JOB
            String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(taskPlan.getOrgId());
            this.deleteTaskJob(id, jobGroupName);
            return Boolean.TRUE;
        }
        throw new BusinessException(MessageUtil.get("task.delete_error"));

    }

    @Override
    public Boolean updateTaskStatus(Long taskId, Integer status) {

        TaskPlan sysTaskPlan = this.getById(taskId);
        if (Objects.isNull(sysTaskPlan)) {
            throw new BusinessException(MessageUtil.get("task.not_exist"));
        }
        // 判断待修改的状态是否与当前状态一直
        if (Objects.equals(status, sysTaskPlan.getStatus())) {
            throw new BusinessException(ResultTypeEnum.PARAM_ERROR.getMessage());
        }
        // 校验待禁用的任务编排是否存在正在运行中的任务实例
        if (Objects.equals(status, TaskStatusEnum.DISABLED.getCode())) {
            // 查询任务实例的状态（初始化中、运行中、暂停（手动）、等待中）不可以删除、禁用
            Boolean run = taskInstanceService.checkInstanceForRun(taskId);
            if (run) {
                throw new BusinessException(MessageUtil.get("task.status_executing_task_not_disable"));
            }
        }
        // 封装数据
        TaskPlan taskPlan = new TaskPlan();
        taskPlan.setId(taskId);
        taskPlan.setStatus(status);
        boolean update = this.updateById(taskPlan);
        if (update) {
            // 更新JOB状态
            String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(sysTaskPlan.getOrgId());
            this.updateTaskJobStatus(buildUpdateTaskPlanJobStatusVO(taskId, status), jobGroupName);
            return Boolean.TRUE;
        }
        throw new BusinessException(MessageUtil.get("task.update.status_error"));
    }

    @Override
    public void executeNow(Long taskId) {
        TaskPlanResourceDTO taskPlanResourceDTO = this.baseMapper.getTaskPlanAndResourceInfoIgnoreTenantId(taskId);
        if (Objects.isNull(taskPlanResourceDTO)) {
            throw new BusinessException(MessageUtil.get("task.not_exist"));
        }
        // 检验任务编排状态
        Integer taskPlanStatus = taskPlanResourceDTO.getStatus();
        if (Objects.equals(taskPlanStatus, TaskStatusEnum.DISABLED.getCode())) {
            throw new BusinessException(MessageUtil.get("task.status_disable_msg"));
        }
        // 检验任务资源配置状态
        TaskResourceConfigEntity taskResourceConfigEntity = taskPlanResourceDTO.getTaskResourceConfigEntity();
        Integer status = taskResourceConfigEntity.getStatus();
        if (Objects.equals(status, ResourceDataStatusEnum.ABNORMAL.getCode())) {
            throw new BusinessException(MessageUtil.get("task.corr_resource_config_error"));
        }

        // 构建任务编排JOB分组名称
        String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(taskPlanResourceDTO.getOrgId());
        this.executeNowTaskJob(taskId, jobGroupName);
    }

    @Override
    public Long addTaskJob(AddTaskPlanJobVO addTaskPlanJobVO) {

        // 校验cron表达式
        String cron = addTaskPlanJobVO.getCron();
        if (!CronUtils.isValid(cron)) {
            throw new BusinessException(MessageUtil.get("task.cron_error"));
        }
        String jobGroupName = addTaskPlanJobVO.getJobGroupName();
        // 定时任务上下文传递参数
        Map<String, Object> paramMap = Maps.newHashMap();
        Long taskPlanId = addTaskPlanJobVO.getTaskPlanId();
        paramMap.put(TaskPlanSchedulerConstant.TASK_PLAN_ID, taskPlanId);
        paramMap.put(TaskPlanSchedulerConstant.TASK_PLAN_GROUP_ID, addTaskPlanJobVO.getTaskPlanGroupId());
        paramMap.put(TaskPlanSchedulerConstant.TASK_PLAN_IS_ASYNC, addTaskPlanJobVO.getAsync());
        paramMap.put(TaskPlanSchedulerConstant.TASK_PLAN_NODE_ID, addTaskPlanJobVO.getNodeId());
        paramMap.put(TaskPlanSchedulerConstant.TASK_PLAN_INCR_LOG, addTaskPlanJobVO.getIsIncrementalLog());

        try {
            quartzJobManager.addJob(TaskPlanQuartzTaskJob.class, taskPlanId.toString(), jobGroupName, cron, paramMap);
            log.debug("-------创建任务编排定时任务,jobName：【{}】,jobGroupName：【{}】", taskPlanId, jobGroupName);

            // 判断是否需要暂停执行调度任务
            Boolean isPause = addTaskPlanJobVO.getIsPause();
            if (Objects.nonNull(isPause) && isPause) {
                log.debug("-------任务编排定时任务,jobName：【{}】,jobGroupName：【{}】，添加后暂停", taskPlanId, jobGroupName);
                quartzJobManager.pauseJob(taskPlanId.toString(), jobGroupName);
            }
        } catch (Exception e) {
            log.error("任务编排添加定时任务异常！", e);
            throw new BusinessException(MessageUtil.get("task.add_quartz_job_error"));
        }
        return addTaskPlanJobVO.getNodeId();
    }

    @Override
    public void updateTaskJobCron(AddTaskPlanJobVO addTaskPlanJobVO) {

        // 校验cron表达式
        String cron = addTaskPlanJobVO.getCron();
        if (!CronUtils.isValid(cron)) {
            throw new BusinessException(MessageUtil.get("task.cron_error"));
        }
        Long taskPlanId = addTaskPlanJobVO.getTaskPlanId();
        TaskPlan taskPlan = this.getById(taskPlanId);
        // 构建JOB分组名称
        String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(taskPlan.getOrgId());
        try {
            quartzJobManager.updateJob(taskPlanId.toString(), jobGroupName, cron);
            log.debug("-------任务编排定时任务执行Cron表达式【{}】修改,jobName：【{}】,jobGroupName：【{}】", cron, taskPlanId, jobGroupName);

            // 判断是否需要暂停执行调度任务
            if (Objects.equals(taskPlan.getStatus(), TaskStatusEnum.DISABLED.getCode())) {
                log.debug("-------任务编排定时任务执行Cron表达式【{}】修改,jobName：【{}】,jobGroupName：【{}】，Cron表达式更新后后暂停", cron,
                        taskPlanId, jobGroupName);
                quartzJobManager.pauseJob(taskPlanId.toString(), jobGroupName);
            }
        } catch (Exception e) {
            log.error("任务编排定时任务执行Cron表达式修改异常！", e);
            throw new BusinessException(MessageUtil.get("task.update_quartz_job_cron_error"));
        }
    }

    @Override
    public void updateTaskJobCronAndParam(AddTaskPlanJobVO taskPlanJobVO, Integer taskStatus) {

        // 校验cron表达式
        String cron = taskPlanJobVO.getCron();
        if (!CronUtils.isValid(cron)) {
            throw new BusinessException(MessageUtil.get("task.cron_error"));
        }
        Long taskPlanId = taskPlanJobVO.getTaskPlanId();
        String jobGroupName = taskPlanJobVO.getJobGroupName();

        // 定时任务上下文传递参数
        Map<String, Object> paramMap = quartzJobManager.buildTaskPlanJobDataMap(taskPlanJobVO);
        try {
            // 更新频率与参数
            quartzJobManager.updateJobAndStatus(taskPlanId.toString(), jobGroupName, cron, paramMap, taskStatus);

        } catch (Exception e) {
            log.error("任务编排定时任务执行更新异常！", e);
            throw new BusinessException(MessageUtil.get("task_update_quartz_job_error"));
        }

    }


    @Override
    public void updateTaskJobStatus(UpdateTaskPlanJobStatusVO updateTaskPlanJobStatusVO, String jobGroupName) {

        Long taskPlanId = updateTaskPlanJobStatusVO.getTaskPlanId();
        Integer taskPlanStatus = updateTaskPlanJobStatusVO.getTaskPlanStatus();
        try {
            // 任务编排为禁用状态则暂停执行任务
            if (Objects.equals(TaskStatusEnum.DISABLED.getCode(), taskPlanStatus)) {
                log.debug("任务编排定时任务,jobName：【{}】,jobGroupName：【{}】状态为暂停：【{}】", taskPlanId.toString(), jobGroupName,
                        taskPlanStatus);
                quartzJobManager.pauseJob(taskPlanId.toString(), jobGroupName);
            } else if (Objects.equals(TaskStatusEnum.ENABLED.getCode(), taskPlanStatus)) {
                // 任务编排为启用状态则恢复执行任务
                quartzJobManager.resumeJob(taskPlanId.toString(), jobGroupName);
            } else {
                throw new BusinessException("任务编排定时任务的状态码标识异常！");
            }
        } catch (Exception e) {
            log.error("任务编排定时任务状态修改异常！", e);
            throw new BusinessException(MessageUtil.get("task.update_quartz_job_status_error"));
        }

    }

    @Override
    public void executeNowTaskJob(Long taskPlanId, String jobGroupName) {
        try {
            quartzJobManager.executeTriggerJob(taskPlanId.toString(), jobGroupName);
            log.debug("-------任务编排定时任务,jobName：【{}】,jobGroupName：【{}】，立即执行", taskPlanId, jobGroupName);
        } catch (Exception e) {
            log.error("任务编排定时任务立即执行异常！", e);
            throw new BusinessException(MessageUtil.get("task.execute_now_job_error"));
        }
    }

    @Override
    public void deleteTaskJob(Long taskPlanId, String jobGroupName) {
        try {
            quartzJobManager.deleteJob(taskPlanId.toString(), jobGroupName);
            log.debug("-------任务编排定时任务,jobName：【{}】,jobGroupName：【{}】，删除", taskPlanId, jobGroupName);
        } catch (Exception e) {
            log.error("任务编排定时任务删除异常！", e);
            throw new BusinessException(MessageUtil.get("task.delete_quartz_job_error"));
        }
    }

    @Override
    public List<ServerProgramEntity> serverPrograms() {
        // 返回服务节点的ID、名称、状态
        LambdaQueryWrapper<ServerProgramEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(ServerProgramEntity::getId, ServerProgramEntity::getProgramName,
                ServerProgramEntity::getStatus);
        // 不晓得为什么要在这里指定逻辑删除
        queryWrapper.eq(ServerProgramEntity::getDeleted, Boolean.FALSE);
        return serverProgramService.list(queryWrapper);
    }

    @Override
    public TaskPlanResourceDTO getTaskPlanAndResourceInfoIgnoreTenantId(Long taskPlanId) {
        return this.baseMapper.getTaskPlanAndResourceInfoIgnoreTenantId(taskPlanId);
    }

    @Override
    public List<ScheduleTaskPlanVO> getSchedulerViewStatistics() {

        List<ScheduleTaskPlanVO> schedulerViewStatistics = this.baseMapper.getSchedulerViewStatistics();
        // 获取系统数据库中所有的状态code信息
        List<Integer> status =
                schedulerViewStatistics.stream().map(ScheduleTaskPlanVO::getStatus).distinct().collect(Collectors.toList());

        // 获取枚举定义的状态code信息
        List<Integer> enumCodes =
                Arrays.stream(TaskStatusEnum.values()).map(TaskStatusEnum::getCode).collect(Collectors.toList());

        // 获取两者的差集
        List<Integer> diffStatus =
                enumCodes.stream().filter(item -> !status.contains(item)).collect(Collectors.toList());

        // 差集不为空，进行默认数据填充
        if (CollectionUtils.isNotEmpty(diffStatus)) {
            ScheduleTaskPlanVO scheduleTaskPlanVO;
            BigInteger zero = BigInteger.ZERO;
            for (Integer stateCode : diffStatus) {
                scheduleTaskPlanVO = ScheduleTaskPlanVO.builder().status(stateCode).count(zero).build();
                schedulerViewStatistics.add(scheduleTaskPlanVO);
            }
        }

        return schedulerViewStatistics;
    }

    @Override
    public List<TaskPlan> getAllListIgnoreTenantId() {
        return this.baseMapper.getAllListIgnoreTenantId();
    }

    /**
     * 校验任务配置json格式
     *
     * @param jsonConfig json格式
     */
    private void validTaskJsonConfig(String jsonConfig) {

        if (StringUtils.isBlank(jsonConfig)) {
            return;
        }

        // 校验是否是数组Json格式
        boolean jsonArray = JSONUtil.isJsonArray(jsonConfig);
        if (!jsonArray) {
            throw new BusinessException(MessageUtil.get("task.config_param_error"));
        }

        JSONArray jsonArr = JSONUtil.parseArray(jsonConfig);
        for (Object obj : jsonArr) {
            if (Objects.isNull(obj)) {
                continue;
            }
            // 判断参数是否是Map类型
            if (obj instanceof Map) {
                Map<String,Object> map =  JSONUtil.toBean(JSONUtil.toJsonStr(obj),  new TypeReference<>(){},true);
                Object paramName = map.get(TaskJsonConfigConstant.PARAM_NAME);
                if (Objects.isNull(paramName)) {
                    throw new BusinessException(MessageUtil.get("task.config_param_name_empty"));
                }

                Object paramTypeObj = map.get(TaskJsonConfigConstant.PARAM_TYPE);
                if (Objects.isNull(paramTypeObj)) {
                    throw new BusinessException(MessageUtil.get("task.config_param_data_type_empty"));
                }
                String typeName = CommonUtil.getDataTypeNameByType(paramTypeObj.toString());
                if (StringUtils.isBlank(typeName)) {
                    throw new BusinessException(MessageUtil.get("task.config_param_data_type_error"));
                }

                Object paramValue = map.get(TaskJsonConfigConstant.PARAM_VALUE);
                if (Objects.isNull(paramValue)) {
                    throw new BusinessException(MessageUtil.get("task.config_param_value_empty"));
                }
            } else {
                throw new BusinessException(MessageUtil.get("task.config_param_error"));
            }
        }
    }

    /**
     * 构建任务编排调度计划实体
     *
     * @param taskPlan 任务编排实体参数
     * @return 结果信息
     */
    private AddTaskPlanJobVO buildAddTaskPlanJobVO(TaskPlan taskPlan) {
        String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(taskPlan.getOrgId());
        // 禁用状态时暂定执行任务
        boolean isPause = Objects.equals(taskPlan.getStatus(), TaskStatusEnum.DISABLED.getCode());
        TaskPlanGroup planGroup = taskPlanGroupService.getById(taskPlan.getGroupId());
        // 构建实体
        return AddTaskPlanJobVO.builder().taskPlanId(taskPlan.getId()).cron(taskPlan.getTaskCron()).async(false)
                        .isPause(isPause).nodeId(taskPlan.getServerProgramId()).jobGroupName(jobGroupName)
                        .taskGroupName(planGroup.getGroupName())
                        .taskPlanGroupId(taskPlan.getGroupId()).isIncrementalLog(true).isParallel(false)
                        .build();
    }

    /**
     * 构建任务编排状态变更调度计划实体
     *
     * @param taskId 任务编排实体
     * @param status 任务编排状态
     * @return 结果信息
     */
    private UpdateTaskPlanJobStatusVO buildUpdateTaskPlanJobStatusVO(Long taskId, Integer status) {
        return UpdateTaskPlanJobStatusVO.builder().taskPlanStatus(status).taskPlanId(taskId).build();
    }

    /**
     * 更新任务编排状态
     *
     * @param taskId    任务编排ID
     * @param groupId   任务分组ID--此处是组织ID
     * @param status    待更新的状态
     * @param sysStatus 更新前的系统数据状态
     */
    private void updateTaskState(Long taskId, Long groupId, Integer status, Integer sysStatus) {
        if (Objects.equals(status, sysStatus)) {
            return;
        }
        // 校验待禁用的任务编排是否存在正在运行中的任务实例
        if (Objects.equals(status, TaskStatusEnum.DISABLED.getCode())) {
            // 查询任务实例的状态（初始化中、运行中、暂停（手动）、等待中）不可以删除、禁用
            Boolean run = taskInstanceService.checkInstanceForRun(taskId);
            if (run) {
                throw new BusinessException(MessageUtil.get("task.status_executing_task_not_disable"));
            }
        }
        // 更新JOB状态
        String jobGroupName = TaskScheduleJobUtil.buildJobGroupName(groupId);
        this.updateTaskJobStatus(buildUpdateTaskPlanJobStatusVO(taskId, status), jobGroupName);
    }

    /**
     * 根据计划名称、id查询是否存在任务计划
     * <p>
     * 校验是否存在同名的任务编排
     *
     * @param taskPlan 查询参数
     */
    private void checkTaskPlaExist(TaskPlan taskPlan) {
        // 校验是否存在同名的任务编排名称
        LambdaQueryWrapper<TaskPlan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskPlan::getTaskName, taskPlan.getTaskName());
        queryWrapper.ne(Objects.nonNull(taskPlan.getId()), TaskPlan::getId, taskPlan.getId());
        TaskPlan sysTaskPlan = this.getOne(queryWrapper);
        // 校验是否存在同名的任务编排名称
        if (Objects.nonNull(sysTaskPlan)) {
            throw new BusinessException(MessageUtil.get("task.plan.name_exist"));
        }

        if(Objects.isNull(taskPlan.getGroupId())){
            throw new BusinessException(MessageUtil.get("task.plan.group_can_not_be_null"));
        }

        if(Const.TaskPlanGroup.TASK_PLAN_GROUP_ROOT_NODE_ID.equals(taskPlan.getGroupId())){
            throw new BusinessException(MessageUtil.get("task.plan.group_can_not_be_root"));
        }
    }
}
